/**
 * Project: yui3-common-mybatisx-core
 * Class PaginationInnerInterceptor
 * Version 1.0
 * File Created at 2020-12-8
 * $Id$
 * author yuyi
 * email 1060771195@qq.com
 */
package yui.comn.mybatisx.extension.plugins.inner;

import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.PageList;
import com.baomidou.mybatisplus.core.toolkit.ParameterUtils;
import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.pagination.dialects.IDialect;

import lombok.NoArgsConstructor;

/**
 * 分页拦截器
 * <p>
 * 默认对 left join 进行优化,虽然能优化count,但是加上分页的话如果1对多本身结果条数就是不正确的
 *
 * @author hubin
 * @since 3.4.0
 */
// @Data
@NoArgsConstructor
@SuppressWarnings({"rawtypes"})
public class PaginationCacheInterceptor extends PaginationInnerInterceptor {
    
    public PaginationCacheInterceptor(DbType dbType) {
        super(dbType);
    }

    public PaginationCacheInterceptor(IDialect dialect) {
        super(dialect);
    }

    @Override
    public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter,
                               RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
            throws SQLException {
        IPage<?> page = ParameterUtils.findPage(parameter).orElse(null);
        if (page == null || page.getSize() < 0 || !page.isSearchCount()) {
            return true;
        }
    
        BoundSql countSql;
        MappedStatement countMs = buildCountMappedStatement(ms, page.countId());
        if (countMs != null) {
            countSql = countMs.getBoundSql(parameter);
        } else {
            countMs = buildAutoCountMappedStatement(ms);
            String countSqlStr = autoCountSql(page.optimizeCountSql(), boundSql.getSql());
            PluginUtils.MPBoundSql mpBoundSql = PluginUtils.mpBoundSql(boundSql);
            countSql = new BoundSql(countMs.getConfiguration(), countSqlStr, mpBoundSql.parameterMappings(), parameter);
            PluginUtils.setAdditionalParameter(countSql, mpBoundSql.additionalParameters());
        }
    
        CacheKey cacheKey = executor.createCacheKey(countMs, parameter, rowBounds, countSql);
        Object result2 = executor.query(countMs, parameter, rowBounds, resultHandler, cacheKey, countSql);
        Object result = null;
        if (result2 instanceof PageList) {
            result = ((PageList) result2).getRecords().get(0);
        } else {
            result = ((ArrayList) result2).get(0);
        }
        page.setTotal(result == null ? 0L : Long.parseLong(result.toString()));
        return continuePage(page);
    }

    
    
}

